package com.ltkj.baseplatform.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ltkj.common.core.utils.StringUtils;
import com.ltkj.common.core.web.domain.AjaxResult;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.alibaba.fastjson.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

/**
 * @Author: chenzeen
 * @Date: 2023/09/05
 * @Description:
 */
@Component
@RefreshScope
public class SendSmsUtil {
    //1709b7800f2f43fdaf31ee5fe48b5b2b
    @Value("${sms.accessKey}")
    private String accessKey;

    //1c5dc5b006f34365b69d97c6c023c989
    @Value("${sms.securityKey}")
    private String securityKey;

    /**
     * 发送短信
     *
     * @param phone         手机号
     * @param signName      签名
     * @param templateCode  模板编码
     * @param templateParam 根据模板中的变量填写, 内容是 JSON 字符串
     * @throws Exception
     */
    public AjaxResult sendSms(String phone, String signName, String templateCode, String templateParam) {
        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isEmpty(phone)) {
            return AjaxResult.error("手机号不能为空");
        }

        if (StringUtils.isEmpty(signName)) {
            signName = "天翼云测试";
        }

        if (StringUtils.isEmpty(templateCode)) {
            templateCode = "SMS64124870510";
        }
        params.put("action", "SendSms");
        params.put("phoneNumber", phone);//手机号
        params.put("signName", signName); //签名
        params.put("templateCode", templateCode);//模板编码
        //{\"code\":\""+code+"\"}
        params.put("templateParam", templateParam);//根据模板中的变量填写, 内容是 JSON 字符串
        String body = JSONObject.toJSONString(params);

        // SETUP1:获取 AccessKey 和 SecurityKey
//        String accessKey = "1709b7800f2f43fdaf31ee5fe48b5b2b";//填写控制台->个人中心->用户 AccessKey->查看->AccessKey
//        String securityKey = "1c5dc5b006f34365b69d97c6c023c989";//填写控制台->个人中心->用户 AccessKey->查看->SecurityKey
        // SETUP2:构造时间戳
        try {
            SimpleDateFormat TIME_FORMATTER = new
                    SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
            SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyyMMdd");
            Date nowdate = new Date();
            String singerDate = TIME_FORMATTER.format(nowdate);
            String singerDd = DATE_FORMATTER.format(nowdate);
//        System.out.println("singerDate:" + singerDate);
//        System.out.println("singerDd:" + singerDd);
            // SETUP3:构造请求流水号
            String uuId = UUID.randomUUID().toString();
//        System.out.println("uuId:" + uuId);
            // SETUP4:构造待签名字符串
            String CampmocalHeader = String.format("ctyun-eop-request-id:%s\neop-date:%s\n", uuId, singerDate);//uuid 去掉 this
            //header 的 key 按照 26 字母进行排序, 以&作为连接符连起来
            URL url = new URL("https://sms-global.ctapi.ctyun.cn/sms/api/v1");
            String query = url.getQuery();
            String afterQuery = "";
            if (query != null) {
                String param[] = query.split("&");
                Arrays.sort(param);
                for (String str : param) {
                    if (afterQuery.length() < 1) {
                        afterQuery = afterQuery + str;
                    } else {
                        afterQuery = afterQuery + "&" + str;
                    }
                }
            }
            // String body ="";
            String calculateContentHash = getSHA256(body); //报文原封不动进行 sha256 摘要
            String sigtureStr = CampmocalHeader + "\n" + afterQuery + "\n" +
                    calculateContentHash;
//        System.out.println("calculateContentHash：" + calculateContentHash);
//        System.out.println("sigtureStr：" + sigtureStr);

            // SETUP5:构造签名
            byte[] ktime = HmacSHA256(singerDate.getBytes(),
                    securityKey.getBytes());
            byte[] kAk = HmacSHA256(accessKey.getBytes(), ktime);
            byte[] kdate = HmacSHA256(singerDd.getBytes(), kAk);
            String Signature =
                    Base64.getEncoder().encodeToString(HmacSHA256(sigtureStr.getBytes("UTF-8"),
                            kdate));

            // SETUP6:构造请求头
            HttpPost httpPost = new HttpPost(String.valueOf(url));
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            httpPost.setHeader("ctyun-eop-request-id", uuId);
            httpPost.setHeader("Eop-date", singerDate);
            String signHeader = String.format("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", accessKey, Signature);
            httpPost.setHeader("Eop-Authorization", signHeader);
//        System.out.println("Signature" + Signature);
//        System.out.println("signHeader" + signHeader);
            httpPost.setEntity(new StringEntity(body,
                    ContentType.create("application/json", "utf-8")));
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String string = EntityUtils.toString(response.getEntity(), "utf-8");
            cn.hutool.json.JSONObject object = JSONUtil.parseObj(string);
            if ("OK".equals(object.get("code"))) {
                return AjaxResult.success();
            } else {
                return AjaxResult.error("" + object.get("message"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    private static String toHex(byte[] data) {
        StringBuilder sb = new StringBuilder(data.length * 2);
        byte[] var2 = data;
        int var3 = data.length;
        for (int var4 = 0; var4 < var3; ++var4) {
            byte b = var2[var4];
            String hex = Integer.toHexString(b);
            if (hex.length() == 1) {
                sb.append("0");
            } else if (hex.length() == 8) {
                hex = hex.substring(6);
            }
            sb.append(hex);
        }
        return sb.toString().toLowerCase(Locale.getDefault());
    }

    private static String getSHA256(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            // byte[] a = text.getBytes(StandardCharsets.UTF_8);

            md.update(text.getBytes(StandardCharsets.UTF_8));
            return toHex(md.digest());
        } catch (NoSuchAlgorithmException var3) {
            return null;
        }
    }

    private static byte[] HmacSHA256(byte[] data, byte[] key) throws
            Exception {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(key, "HmacSHA256"));
            return mac.doFinal(data);
        } catch (Exception e) {
            return null;
        }
    }
}
